/**
 * 
 */
package com.alstudio.net.protocol.xmpp;

import java.util.ArrayList;

import android.os.Handler;
import android.os.Message;

import com.alstudio.app.LocalEnv;
import com.alstudio.pojo.LocalData;
import com.alstudio.ui.base.BaseActivity;
import com.alstudio.utils.log.Mylog;

/**
 * 此类用于接收到网络事件后，查询xmpp消息接收队列，通过回调函数，采用事件通知的方式驱动UI做界面更新。
 * UI界面通过registerListener函数将本身注册到xmpp消息接收队列中，调用unRegisterListener将自身从xmpp消息接收队列
 * 移除。当事件
 * 
 * @author Alonso Lee
 * 
 */
public class XmppEventNotifyManager {

	/* 调试TAG */
	private final String TAG = "XmppEventNotifier";
	/* xmpp消息接收队列,此列表保存需要接收xmpp 事件的界面 */
	private ArrayList<BaseActivity> listenerList;

	private final int NOTIFY_UI_XMPP_EVENT_OCCURED = 10086;

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what) {
			case NOTIFY_UI_XMPP_EVENT_OCCURED:
				LocalData data = (LocalData) msg.obj;
				startNotifyUIListener(data);
				break;
			}
		}
	};

	/**
	 * 创建Notifier，初始化xmpp消息接收队列
	 * 
	 * @author Alonso Lee
	 */
	public XmppEventNotifyManager() {
		// 初始化xmpp消息接收队列
		listenerList = new ArrayList<BaseActivity>();
	}

	/**
	 * 将指定界面增加到xmpp消息接收队列中
	 * 
	 * @param activity
	 *            加入到xmpp消息接收队列的界面对象
	 * @author Alonso Lee
	 */
	public void registerListener(BaseActivity activity) {
		if (!listenerList.contains(activity)) {
			Mylog.i("register Xmpp Event Listener for " + activity.activityName);
			listenerList.add(activity);
		}
	}

	/**
	 * 将指定界面从xmpp消息队列中移除
	 * 
	 * @param activity
	 *            需要从移除的界面
	 * @author Alonso Lee
	 */
	public void unRegisterListener(BaseActivity activity) {
		if (activity != null) {
			if (listenerList.contains(activity)) {
				Mylog.i("unregister Xmpp Event Listener for "
						+ activity.activityName);
				listenerList.remove(activity);
			}
		}
	}

	/**
	 * 根据不同的消息类型，调用不同的回调函数通知UI
	 * 
	 * @param type
	 *            消息类型
	 * @param data
	 *            回调数据
	 */
	public void notifyAllListener(LocalData data) {
		android.os.Message msg = mHandler
				.obtainMessage(NOTIFY_UI_XMPP_EVENT_OCCURED);
		msg.obj = data;
		mHandler.sendMessage(msg);
	}

	/**
	 * 获取注册到xmpp消息队列的界面列表
	 * 
	 * @return null 表示当前列表中没有任何界面
	 * @author Alonso Lee
	 */
	public ArrayList<BaseActivity> getXmppEventListeners() {
		if (listenerList.size() > 0) {
			return this.listenerList;
		}
		// 当前没有任何界面注册到队列中，直接返回null
		return null;
	}

	private void startNotifyUIListener(LocalData data) {
		switch (data.getType()) {
		case XMPP_CONNECTION_STATE_CHANGED_EVENT:
			notifyConnectionStateChange(data);
			break;
		case XMPP_CONNECTION_ESTABLISHED_EVENT:
			notifyConnectionEstablished();
			break;
		case XMPP_CONNECTION_LOST_EVENT:
			notifyConnectionLost(data);
			break;
		case XMPP_AUTH_FAILED_EVENT:
			notifyAuthFailed(data);
			break;
		case XMPP_LOGOUT_SUCCESS_EVENT:
			notifyLogoutEvent(data);
			break;
		case XMPP_IQ_PACKAGE_RECEIVE_EVENT:
			break;
		case XMPP_MESSAGE_PACKAGE_RECEIVE_EVENT:
			break;
		case XMPP_PRESENCE_PACKAGE_RECEIVE_EVENT:
			break;
		}
	}

	private void notifyConnectionStateChange(LocalData data) {
		ArrayList<BaseActivity> mListeners = LocalEnv.mXmppEventNotifyManager
				.getXmppEventListeners();
		if (mListeners != null) {
			for (BaseActivity b : mListeners) {
				if (b.isCallbackEnable()) {
					b.handleConnectStateChangedEvent(
							data.getNewConnectionState(),
							data.getLastConnectionState());
				} else {
					Mylog.i("ignore notify " + b.activityName);
				}
			}
		}
	}

	private void notifyConnectionEstablished() {
		ArrayList<BaseActivity> mListeners = LocalEnv.mXmppEventNotifyManager
				.getXmppEventListeners();
		if (mListeners != null) {
			for (BaseActivity b : mListeners) {
				if (b.isCallbackEnable()) {
					b.handleLoginedEvent();
				} else {
					Mylog.i("ignore notify " + b.activityName);
				}
			}
		}
	}

	private void notifyConnectionLost(LocalData data) {
		ArrayList<BaseActivity> mListeners = LocalEnv.mXmppEventNotifyManager
				.getXmppEventListeners();
		if (mListeners != null) {
			for (BaseActivity b : mListeners) {
				if (data.getErrorMessage().contains("conflict")) {
					if (b.isCallbackEnable()) {
						// 被踢下线了
						b.handlerOnConflictEvent();
					} else {
						Mylog.i("ignore notify " + b.activityName);
					}
				} else {
					if (b.isCallbackEnable()) {
						b.handleConnectionLostEvent(data.getErrorMessage());
					} else {
						Mylog.i("ignore notify " + b.activityName);
					}
				}
			}
		}
	}

	private void notifyAuthFailed(LocalData data) {
		ArrayList<BaseActivity> mListeners = LocalEnv.mXmppEventNotifyManager
				.getXmppEventListeners();
		if (mListeners != null) {
			for (BaseActivity b : mListeners) {
				if (b.isCallbackEnable()) {
					// 账号验证失败
					b.handleAuthFailedEvent(data.getErrorMessage());
				} else {
					Mylog.i("ignore notify " + b.activityName);
				}
			}
		}
	}

	private void notifyLogoutEvent(LocalData data) {
		ArrayList<BaseActivity> mListeners = LocalEnv.mXmppEventNotifyManager
				.getXmppEventListeners();
		if (mListeners != null) {
			for (BaseActivity b : mListeners) {
				if (b.isCallbackEnable()) {
					// 注销成功
					b.handleLogoutEvent();
				} else {
					Mylog.i("ignore notify " + b.activityName);
				}
			}
		}
	}

}
